#include "mainwindow.h"
#include "downloadmanager.h"
#include "downloaditem.h"
#include "settingsmanager.h"
#include "settingsdialog.h"
#include "downloadhistory.h"
#include "notificationmanager.h"
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QDialog>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QListWidget>
#include <QtCore/QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_downloadManager(new DownloadManager(this))
    , m_settingsManager(new SettingsManager(this))
    , m_settingsDialog(nullptr)
    , m_downloadHistory(new DownloadHistory(this))
    , m_notificationManager(new NotificationManager(this))
{
    setupUI();
    setupMenu();
    setupToolbar();
    setupTable();
    setupStatusBar();
    
    setWindowTitle("Download Manager");
    resize(800, 600);
}

MainWindow::~MainWindow()
{
}

void MainWindow::setupUI()
{
    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
    
    // 创建工具栏区域
    m_toolbar = new QToolBar(this);
    addToolBar(m_toolbar);
    
    // 创建表格区域
    m_downloadTable = new QTableWidget(this);
    mainLayout->addWidget(m_downloadTable);
}

void MainWindow::setupMenu()
{
    QMenuBar *menuBar = new QMenuBar(this);
    setMenuBar(menuBar);
    
    QMenu *fileMenu = menuBar->addMenu("&File");
    QAction *addAction = fileMenu->addAction("&Add URL...");
    QAction *settingsAction = fileMenu->addAction("&Settings...");
    QAction *historyAction = fileMenu->addAction("&Download History...");
    QAction *exitAction = fileMenu->addAction("E&xit");
    
    connect(addAction, &QAction::triggered, this, &MainWindow::addDownload);
    connect(settingsAction, &QAction::triggered, this, &MainWindow::openSettings);
    connect(historyAction, &QAction::triggered, [=]() {
        // 显示下载历史记录对话框
        QMessageBox::information(this, "Download History", "Download history feature would be implemented here");
    });
    connect(exitAction, &QAction::triggered, this, &QMainWindow::close);
    
    QMenu *downloadMenu = menuBar->addMenu("&Download");
    QAction *startAction = downloadMenu->addAction("&Start");
    QAction *pauseAction = downloadMenu->addAction("&Pause");
    QAction *removeAction = downloadMenu->addAction("&Remove");
    
    connect(startAction, &QAction::triggered, this, &MainWindow::startDownload);
    connect(pauseAction, &QAction::triggered, this, &MainWindow::pauseDownload);
    connect(removeAction, &QAction::triggered, this, &MainWindow::removeDownload);
}

void MainWindow::setupToolbar()
{
    m_toolbar->setMovable(false);
    
    QAction *addAction = m_toolbar->addAction(QIcon(":/icons/add.png"), "Add");
    QAction *startAction = m_toolbar->addAction(QIcon(":/icons/start.png"), "Start");
    QAction *pauseAction = m_toolbar->addAction(QIcon(":/icons/pause.png"), "Pause");
    QAction *removeAction = m_toolbar->addAction(QIcon(":/icons/remove.png"), "Remove");
    
    connect(addAction, &QAction::triggered, this, &MainWindow::addDownload);
    connect(startAction, &QAction::triggered, this, &MainWindow::startDownload);
    connect(pauseAction, &QAction::triggered, this, &MainWindow::pauseDownload);
    connect(removeAction, &QAction::triggered, this, &MainWindow::removeDownload);
}

void MainWindow::setupTable()
{
    m_downloadTable->setColumnCount(8); // 增加分类列
    m_downloadTable->setHorizontalHeaderLabels(QStringList() << "File Name" << "URL" << "Status" << "Category" << "Size" << "Downloaded" << "Progress" << "Speed");
    m_downloadTable->horizontalHeader()->setStretchLastSection(true);
    m_downloadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_downloadTable->setSelectionMode(QAbstractItemView::SingleSelection);
    m_downloadTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
}

void MainWindow::setupStatusBar()
{
    m_statusLabel = new QLabel("Ready", this);
    m_statusProgressBar = new QProgressBar(this);
    m_statusProgressBar->setRange(0, 100);
    m_statusProgressBar->setValue(0);
    m_statusProgressBar->setVisible(false);
    
    statusBar()->addWidget(m_statusLabel, 1);
    statusBar()->addPermanentWidget(m_statusProgressBar);
}

void MainWindow::addDownload()
{
    QDialog dialog(this);
    dialog.setWindowTitle("Add Download");
    
    QFormLayout form(&dialog);
    
    QLineEdit *urlEdit = new QLineEdit(&dialog);
    urlEdit->setPlaceholderText("Enter URL to download");
    
    // 添加分类选择
    QComboBox *categoryCombo = new QComboBox(&dialog);
    categoryCombo->addItems(QStringList() << "Default" << "Images" << "Videos" << "Audio" << "Documents" << "Archives" << "Software");
    
    // 添加标签输入
    QLineEdit *tagsEdit = new QLineEdit(&dialog);
    tagsEdit->setPlaceholderText("Enter tags separated by commas");
    
    form.addRow("URL:", urlEdit);
    form.addRow("Category:", categoryCombo);
    form.addRow("Tags:", tagsEdit);
    
    QPushButton *okButton = new QPushButton("OK");
    QPushButton *cancelButton = new QPushButton("Cancel");
    
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addWidget(okButton);
    buttonLayout->addWidget(cancelButton);
    form.addRow(buttonLayout);
    
    connect(okButton, &QPushButton::clicked, &dialog, &QDialog::accept);
    connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject);
    
    if (dialog.exec() == QDialog::Accepted) {
        QString url = urlEdit->text();
        if (!url.isEmpty()) {
            // 添加到下载管理器
            m_downloadManager->addDownload(url);
            
            // 添加到表格
            int row = m_downloadTable->rowCount();
            m_downloadTable->insertRow(row);
            
            DownloadItem *item = m_downloadManager->downloadAt(m_downloadManager->downloadCount() - 1);
            
            // 设置分类和标签
            item->setCategory(categoryCombo->currentText());
            QString tagsText = tagsEdit->text();
            if (!tagsText.isEmpty()) {
                QStringList tags = tagsText.split(",", Qt::SkipEmptyParts);
                item->setTags(tags);
            }
            
            // 设置多线程连接数、最大重试次数和速度限制
            item->setMaxConnections(m_settingsManager->maxConcurrentDownloads());
            item->setMaxRetries(m_settingsManager->maxRetries());
            item->setSpeedLimit(m_settingsManager->downloadSpeedLimit());
            
            QTableWidgetItem *nameItem = new QTableWidgetItem(item->fileName());
            QTableWidgetItem *urlItem = new QTableWidgetItem(url);
            QTableWidgetItem *statusItem = new QTableWidgetItem("Queued");
            QTableWidgetItem *categoryItem = new QTableWidgetItem(item->category());
            QTableWidgetItem *sizeItem = new QTableWidgetItem("Unknown");
            QTableWidgetItem *downloadedItem = new QTableWidgetItem("0 KB");
            QTableWidgetItem *progressItem = new QTableWidgetItem("0%");
            QTableWidgetItem *speedItem = new QTableWidgetItem("0 KB/s");
            
            m_downloadTable->setItem(row, 0, nameItem);
            m_downloadTable->setItem(row, 1, urlItem);
            m_downloadTable->setItem(row, 2, statusItem);
            m_downloadTable->setItem(row, 3, categoryItem);
            m_downloadTable->setItem(row, 4, sizeItem);
            m_downloadTable->setItem(row, 5, downloadedItem);
            m_downloadTable->setItem(row, 6, progressItem);
            m_downloadTable->setItem(row, 7, speedItem);
            
            // 连接信号
            connect(item, &DownloadItem::statusChanged, [=]() {
                updateTableItem(row, item);
            });
            
            connect(item, &DownloadItem::progressChanged, [=](int progress) {
                Q_UNUSED(progress);
                updateTableItem(row, item);
            });
            
            connect(item, &DownloadItem::downloadSpeedChanged, [=](int speed) {
                // 更新速度显示
                QString speedStr;
                if (speed < 1024) {
                    speedStr = QString("%1 B/s").arg(speed);
                } else if (speed < 1024 * 1024) {
                    speedStr = QString("%1 KB/s").arg(speed / 1024);
                } else {
                    speedStr = QString("%1 MB/s").arg(static_cast<double>(speed) / (1024.0 * 1024.0), 0, 'f', 1);
                }
                m_downloadTable->item(row, 7)->setText(speedStr);
            });
            
            connect(item, &DownloadItem::downloadError, this, &MainWindow::onDownloadError);
            connect(item, &DownloadItem::downloadFinished, this, &MainWindow::onDownloadFinished);
            
            // 根据设置决定是否自动开始下载
            if (m_settingsManager->startDownloadOnAdd()) {
                m_downloadManager->startDownload(row);
                updateTableItem(row, item);
            }
        }
    }
}

void MainWindow::startDownload()
{
    QModelIndexList selectedIndexes = m_downloadTable->selectionModel()->selectedRows();
    if (!selectedIndexes.isEmpty()) {
        int row = selectedIndexes.first().row();
        m_downloadManager->startDownload(row);
        
        DownloadItem *item = m_downloadManager->downloadAt(row);
        updateTableItem(row, item);
    }
}

void MainWindow::pauseDownload()
{
    QModelIndexList selectedIndexes = m_downloadTable->selectionModel()->selectedRows();
    if (!selectedIndexes.isEmpty()) {
        int row = selectedIndexes.first().row();
        m_downloadManager->pauseDownload(row);
        
        DownloadItem *item = m_downloadManager->downloadAt(row);
        updateTableItem(row, item);
    }
}

void MainWindow::removeDownload()
{
    QModelIndexList selectedIndexes = m_downloadTable->selectionModel()->selectedRows();
    if (!selectedIndexes.isEmpty()) {
        int row = selectedIndexes.first().row();
        m_downloadManager->removeDownload(row);
        m_downloadTable->removeRow(row);
    }
}

void MainWindow::showDownloadProperties()
{
    QMessageBox::information(this, "Properties", "Download properties would be shown here!");
}

void MainWindow::openSettings()
{
    if (!m_settingsDialog) {
        m_settingsDialog = new SettingsDialog(m_settingsManager, this);
    }
    
    m_settingsDialog->exec();
}

void MainWindow::updateDownloadProgress(DownloadItem *item)
{
    // TODO: 更新下载进度
}

void MainWindow::onDownloadFinished()
{
    m_notificationManager->onDownloadFinished("Download completed");
    m_statusLabel->setText("Download completed");
    statusBar()->showMessage("Download completed", 3000);
}

void MainWindow::onDownloadError(const QString &errorString)
{
    m_notificationManager->onDownloadError("Download failed", errorString);
    m_statusLabel->setText(QString("Error: %1").arg(errorString));
    statusBar()->showMessage(QString("Download error: %1").arg(errorString), 5000);
}

void MainWindow::updateTableItem(int row, DownloadItem *item)
{
    if (row < 0 || row >= m_downloadTable->rowCount()) {
        return;
    }
    
    // 更新状态
    QString statusStr;
    switch (item->status()) {
    case DownloadItem::Queued:
        statusStr = "Queued";
        break;
    case DownloadItem::Downloading:
        statusStr = "Downloading";
        break;
    case DownloadItem::Paused:
        statusStr = "Paused";
        break;
    case DownloadItem::Completed:
        statusStr = "Completed";
        // 显示在状态栏
        m_statusLabel->setText("Download completed");
        statusBar()->showMessage("Download completed", 3000);
        break;
    case DownloadItem::Error:
        statusStr = "Error";
        // 显示在状态栏
        m_statusLabel->setText("Download error occurred");
        break;
    case DownloadItem::Canceled:
        statusStr = "Canceled";
        break;
    }
    
    m_downloadTable->item(row, 2)->setText(statusStr);
    m_downloadTable->item(row, 3)->setText(item->category());
    
    // 更新文件大小
    if (item->fileSize() > 0) {
        QString sizeStr;
        if (item->fileSize() < 1024) {
            sizeStr = QString("%1 B").arg(item->fileSize());
        } else if (item->fileSize() < 1024 * 1024) {
            sizeStr = QString("%1 KB").arg(item->fileSize() / 1024);
        } else {
            sizeStr = QString("%1 MB").arg(static_cast<double>(item->fileSize()) / (1024.0 * 1024.0), 0, 'f', 1);
        }
        m_downloadTable->item(row, 4)->setText(sizeStr);
    }
    
    // 更新已下载大小
    QString downloadedStr;
    if (item->downloadedSize() < 1024) {
        downloadedStr = QString("%1 B").arg(item->downloadedSize());
    } else if (item->downloadedSize() < 1024 * 1024) {
        downloadedStr = QString("%1 KB").arg(item->downloadedSize() / 1024);
    } else {
        downloadedStr = QString("%1 MB").arg(static_cast<double>(item->downloadedSize()) / (1024.0 * 1024.0), 0, 'f', 1);
    }
    m_downloadTable->item(row, 5)->setText(downloadedStr);
    
    // 更新进度
    m_downloadTable->item(row, 6)->setText(QString("%1%").arg(item->progress()));
}